STM32F103硬件IIC在HAL库下入坑指南 |
您所在的位置:网站首页 › STM32 I2C BUG是什么 › STM32F103硬件IIC在HAL库下入坑指南 |
最近在BMS,电压采样芯片用的是TI的bq76940,监测9-15路电压,可进行充、放电控制,数据通信采用IIC模式,我MCU采用的是STM32F103RCT6。 ST采用HAL库,因为之前搞过HAL库的429,比较熟悉,网上又有里程,就直接copy使用了。关于ST的硬件IIC网上绝大部分的文章再说bug太大,都不建议使用,但是同时也有人分享一些使用成功的解决方案,我决定自己摸索一下,顺便挑战一下自己(现在觉得真有病)。 写好代码准备调试, __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_I2C2_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; //IIC2 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;//GPIO_MODE_AF_OD; GPIO_MODE_OUTPUT_PP GPIO_MODE_AF_PP GPIO_InitStruct.Pull = GPIO_NOPULL; //自加nsj GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;//GPIO_SPEED_FREQ_HIGH; GPIO_SPEED_HIGH HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 结果发现程序死在 if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) , 这就是网上说的busy死锁问题,我也终究是逃不过去。经过 最近在BMS,电压采样芯片用的是TI的bq76940,监测9-15路电压,可进行充、放电控制,数据通信采用IIC模式,我MCU采用的是STM32F103RCT6。 ST采用HAL库,因为之前搞过HAL库的429,比较熟悉,网上又有里程,就直接copy使用了。关于ST的硬件IIC网上绝大部分的文章再说bug太大,都不建议使用,但是同时也有人分享一些使用成功的解决方案,我决定自己摸索一下,顺便挑战一下自己(现在觉得真有病)。 写好配置代码准备调试, __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_I2C2_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; //IIC2 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;//手册中要求配置成开漏模式 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 结果发现程序死在 if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) 这就是网上说的busy死锁问题,我也终究是逃不过去。经过查看IIC的SR2寄存器发现只要把GPIO初始化为IIC,busy标志位就会置位。于是我尝试了使用大家普遍的解决方案,在初始化前先对CR1的SWRST复位,如下,发现于事无补。 I2C2->CR1 |= 0x8000; I2C2->CR1 &= ~0x8000; 后来认为应该在IIC初始化之后再对SWRST进行复位,这样才能彻底清除busy位。经过尝试仍然不行。查阅手册发现 只要是监测有低电平该位就会置1,我把IO设置成了开漏输出,IO口肯定不能输出高电平,接着我又查阅了bq76940的推荐电路(原理图按照推荐电路设计) 我发现也没有上拉电阻,我靠,我马上查阅了bq76940芯片是否有内部上拉,然而并没有。没办法,只能刮开电路板,在铜线上焊出了一个上拉电阻,结果发现真的跳过了busy的坑!注意初始化IO之后还是需要复位SWRST的。 先小小高兴了一下,继续调试,发现还是不能进行通信,经过串口打印发现在地址发送之后居然返回的是HAL_ERROR,这说明地址发送未成功。经过查阅手册发现这是与bq76940没有“握手成功”。原因可能有 芯片出现故障引脚连接错误或者虚焊IIC的地址引脚不对。首先排查第1点,直接更换了2套全新的板子,发现故障依旧。接着是第二点,检查了连线和焊盘,都没问题。就剩下第三条地址不对了。我查阅资料发现 我的IIC配置也是7位的地址 我自认为设置并没有问题,但查阅ST的底层发现,我里个去。。。想骂人的心都有 底层中并没有把设备的地址左移,而是直接把最低位改为“0”或“1”!这真实欺负我们这些不看底层的人啊,于是自己把器件地址偷偷的左移了一位。 但是发现仍然不行。我已经快顶不住了,身心俱疲,忽然想到我们还有协议分析仪,一下子激动起来,立刻接上去试验。发现发送的地址、读写位是正确的,跟随的ACK也是有的,但是接下来发送的数据解读出来确认红色的ERROR。 我发现ACK之后的高电平仅有2us左右,而且后面没有出现start信号,于是把IIC的频率从100k降低到50k。哈哈,协议分析仪的数据终于正常了,读写的值也是没有问题的。紧接着用串口打印出读取的数据,与分析仪一对比发现完全不一样(全是0),顿时头大,继续查吧。查来查去,发现自己在进行CRC校验的时候又把地址偷偷的左移了一位 CRCInput[0] = (I2CSlaveAddress |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |